package com.bingo.mall.h5.service;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bingo.common.constant.Constants;
import com.bingo.common.core.domain.model.LoginMember;
import com.bingo.common.utils.*;
import com.bingo.common.utils.ip.AddressUtils;
import com.bingo.common.utils.ip.IpUtils;
import com.bingo.framework.config.LocalDataUtil;
import com.bingo.framework.web.service.TokenService;
import com.bingo.mall.h5.domain.form.H5AccountLoginForm;
import com.bingo.mall.h5.domain.form.RegisterForm;
import com.bingo.mall.h5.domain.vo.H5LoginVO;
import com.bingo.mall.h5.domain.vo.RegisterVO;
import com.bingo.mall.manager.ums.domain.entity.Member;
import com.bingo.mall.manager.ums.domain.entity.MemberLogininfor;
import com.bingo.mall.manager.ums.domain.entity.MemberWechat;
import com.bingo.mall.manager.ums.domain.vo.MemberVO;
import com.bingo.mall.manager.ums.mapper.MemberLogininforMapper;
import com.bingo.mall.manager.ums.mapper.MemberMapper;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;

import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;

@Service
@Slf4j
public class H5MemberService {

    @Autowired
    private MemberMapper memberMapper;



    @Autowired
    private TokenService tokenService;


    @Autowired
    private MemberLogininforMapper memberLogininforMapper;


    /**
     * 注册
     *
     * @param request 注册请求体
     * @return 结果
     */
    @Transactional
    public RegisterVO register(RegisterForm request) {
        LocalDateTime optDate = LocalDateTime.now();
        RegisterVO response = new RegisterVO();
        //校验验证码
        this.validateUserAccount(request.getUserAccount());
        //创建会员
        Member member = new Member();
        member.setPassword(SecurityUtils.encryptPassword(request.getPassword()));
        member.setNickname("用户");
        member.setGender(0);
        member.setCreateTime(optDate);
        int rows = memberMapper.insert(member);
        if (rows < 1) {
            throw new RuntimeException("注册失败，请重试");
        }
        H5LoginVO loginResponse = getLoginResponse(member.getId());
        response.setToken(loginResponse.getToken());
        return response;
    }

    private void validateUserAccount(@NotBlank String userAccount) {
        QueryWrapper<Member> qw = new QueryWrapper<>();
        qw.eq("user_account", userAccount);
        Member member = memberMapper.selectOne(qw);
        if (member != null) {
            throw new RuntimeException("该账号已被占用");
        }
    }


    /**
     * 账号密码登录
     *
     * @param data
     * @return
     */
    public H5LoginVO accountLogin(String data) {
        if (StringUtils.isEmpty(data)) {
            throw new RuntimeException(Constants.LOGIN_INFO.WRONG);
        }
        // 解码 转 对象
        H5AccountLoginForm request = JSON.parseObject(new String(Base64Utils.decodeFromString(data)), H5AccountLoginForm.class);
        log.info("account login request:{}", JSONUtil.toJsonStr(request));
        QueryWrapper<Member> qw = new QueryWrapper<>();
        qw.eq("user_account", request.getUserAccount());
        Member member = memberMapper.selectOne(qw);
        if (member == null) {
            throw new RuntimeException(Constants.LOGIN_INFO.WRONG);
        }
        //check 密码
        if (!SecurityUtils.matchesPassword(request.getPassword(), member.getPassword())) {
            throw new RuntimeException(Constants.LOGIN_INFO.WRONG);
        }
        return getLoginResponse(member.getId());
    }


    /**
     * 封装登录响应
     *
     * @param memberId 登录会员id
     * @return 结果
     */
    public H5LoginVO getLoginResponse(Long memberId) {
        LoginMember loginMember = new LoginMember();
        loginMember.setMemberId(memberId);
        String token = tokenService.createMemberToken(loginMember);
        this.insert(memberId);
        H5LoginVO response = new H5LoginVO();
        response.setToken(token);
        return response;
    }

    public MemberVO getMemberInfo() {
        Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
        MemberVO memberVO = new MemberVO();
        BeanUtils.copyProperties(member, memberVO);

        QueryWrapper<MemberWechat> qw = new QueryWrapper<>();
        qw.eq("member_id", member.getId());
        return memberVO;
    }





    /**
     * 新增会员登录记录
     *
     * @param memberId 会员id
     * @return 结果
     */
    public void insert(Long memberId) {
        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        MemberLogininfor memberLogininfor = new MemberLogininfor();
        memberLogininfor.setMemberId(memberId);
        memberLogininfor.setOs(userAgent.getOperatingSystem().getName());
        memberLogininfor.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
        memberLogininfor.setBrowser(userAgent.getBrowser().getName());
        memberLogininfor.setLoginLocation(AddressUtils.getRealAddressByIP(memberLogininfor.getIpaddr()));
        memberLogininfor.setLoginTime(LocalDateTime.now());
        memberLogininforMapper.insert(memberLogininfor);
    }





    public Member selectById(Long memberId) {
        return memberMapper.selectById(memberId);
    }
}
